#ifndef MAPINFO_H
#define MAPINFO_H

#include "commondefine.h"

#include <QPointF>

// 为了保留层级，暂时修改了带有std::pair的QVector，在地图功能完成后可以继续修改
typedef QVector<QPointF> LanePoint;
typedef QVector<LanePoint> GeometryPoint;
typedef QVector<std::pair<GeometryPoint, int> > LaneSectionPoint;
typedef QVector<LaneSectionPoint> RoadPoint;
typedef QVector<RoadPoint> RoadMapPoint;

#define __MAPDATA (MapInfo::getInstance())

class MapInfo
{
private:
    MapInfo();
    ~MapInfo();

    MapInfo(const MapInfo &);
    MapInfo &operator =(const MapInfo &);

public:
    static MapInfo * getInstance()
    {
        static MapInfo mapInfo;
        return &mapInfo;
    }

    void setHeader(Header &header);
    void setRoad(QVector<SRoad> &qvecRoad);
    void setController(QVector<SController> &qvecController);
    void setJunction(QVector<Junction> &qvecJunction);

    const Header &getHeader() const;
    const QVector<SRoad> &getRoad() const;
    const QVector<SController> &getController() const;
    const QVector<Junction> &getJunction() const;

    // 根据解析获得的道路信息，获取道路表面轮廓点坐标
    int getRoadSurfaceContourPoint(const QVector<SRoad> &qvecAllRoad, RoadMapPoint &roadMapAllPoint) const;
    int getRoadLaneSectionLevelPoint(const RoadMapPoint &roadMapAllPoint, QVector<QVector<GeometryPoint> > &qvecQvecMapPoint) const;

public:
    // 判断浮点数是否为零
    template<typename T>
    static bool isZero(T value);

private:
    // 获取车道段数据
    LaneSectionPoint getLaneSectionPoint(SLaneOffset &laneOffset, SLaneSection &laneSection, QVector<SGeometry> &qvecGeometry, double dLaneStart, double dLaneEnd) const;

    // 获取地理几何元素数据
    QVector<QVector<QPointF> > getGeometryData(const SLaneOffset &laneOffset, const SLaneSection &laneSection, const SGeometry &geometry, double dStartDS, double dEndDS) const;

    // 将相对车道段合并
    void mergeAllRelativelyLaneSection(QVector<QVector<QPointF> > &qvecQvecEachLaneSection, const QVector<QVector<QVector<QPointF> > > &qvecQvecQvecAllRelativelyLaneSection) const;

    // 获取车道数据
    void getGeometryLaneData(const SGeometry &geometry, const SLaneOffset &laneOffset, const SLane &lane, double dSOffset, double dStartDS, double dEndDS, QVector<QVector<QPointF> > &qvecQvecLanesPoint) const;

    void getGeometryLineData(double dSOffset, double dStartDS, double dEndDS, double dStepSize, const SGeometry &geometry, const SLaneOffset &laneOffset, const SLane &lane, QVector<QVector<QPointF> > &qvecQvecLanePoint) const;

    void getGeometrySpiralData(double dSOffset, double dStartDS, double dEndDS, double dStepSize, const SGeometry &geometry, const SLaneOffset &laneOffset, const SLane &lane, QVector<QVector<QPointF> > &qvecQvecLanePoint) const;

    void getGeometryArcData(double dSOffset, double dStartDS, double dEndDS, double dStepSize, const SGeometry &geometry, const SLaneOffset &laneOffset, const SLane &lane, QVector<QVector<QPointF> > &qvecQvecLanePoint) const;

    void getGeometryPoly3Data(double dSOffset, double dStartDS, double dEndDS, double dStepSize, const SGeometry &geometry, const SLane &lane, QVector<QVector<QPointF> > &qvecQvecLanePoint) const;

    double sgn(double dSgnVar) const;

private:
    Header m_header;
    QVector<SRoad> m_qvecRoad;
    QVector<SController> m_qvecController;
    QVector<Junction> m_qvecJunction;
};

#endif // MAPINFO_H
